package com.workingpub.commons.orm.internal;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map.Entry;

import javax.persistence.InheritanceType;

import org.springframework.util.StringUtils;

import com.workingpub.commons.domain.Identifiable;
import com.workingpub.commons.domain.UnDeletable;
import com.workingpub.commons.orm.SqlBuildEntry;

public class SelectBuilder extends AbstractSqlBuilder {

	public <T extends Identifiable<?>> SelectBuilder(Class<T> type) {
		super(type);
	}

	@Override
	protected <T extends Identifiable<?>> SqlBuildEntry build(EntityMetaInfo metaInfo, T entity) throws Exception {
		SqlBuildEntry sqlEntry = new SqlBuildEntry();
		sqlEntry.append("Select ");
		boolean first = true;
		for (String column : metaInfo.getColumnInfos().keySet()) {
			if (first) {
				sqlEntry.append(column);
				first = false;
			} else {
				sqlEntry.append(" ,").append(column);
			}
		}

		if (InheritanceType.SINGLE_TABLE.equals(metaInfo.getInheritanceType())) {
			sqlEntry.append(" ,").append(metaInfo.getDiscriminatorColumn());
		}

		// 解决多表继续时，子类无主键Id标识的问题
		if (StringUtils.hasText(metaInfo.getIdname()) && !metaInfo.getColumnInfos().containsKey(metaInfo.getIdname())) {
			sqlEntry.append(" ," + metaInfo.getIdname());
		}

		sqlEntry.append(" From " + metaInfo.getTableName()).append(" Where 1=1");

		if (StringUtils.hasText(metaInfo.getIdname()) && null != entity.getId()) {
			sqlEntry.append(" And " + metaInfo.getIdname()).append(" = :" + metaInfo.getIdname());
			sqlEntry.putParam(metaInfo.getIdname(), entity.getId());
		}

		if (InheritanceType.SINGLE_TABLE.equals(metaInfo.getInheritanceType())) {
			sqlEntry.append(" And " + metaInfo.getDiscriminatorColumn())
					.append(" = :" + metaInfo.getDiscriminatorColumn());
			sqlEntry.putParam(metaInfo.getDiscriminatorColumn(), metaInfo.getDiscriminatorValue());
		}

		if (entity instanceof UnDeletable && metaInfo.getColumnInfos().containsKey(UnDeletable.Deleted_Flag_Field)) {
			sqlEntry.append(" And " + UnDeletable.Deleted_Flag_Field + " = 0");
		}

		for (Entry<String, Object> entry : metaInfo.getColumnInfos().entrySet()) {
			if (entry.getKey().equalsIgnoreCase(metaInfo.getIdname())) {
				continue;
			}
			if (entry.getKey().equalsIgnoreCase(metaInfo.getDiscriminatorColumn())) {
				continue;
			}
			if (entry.getKey().equalsIgnoreCase(UnDeletable.Deleted_Flag_Field)) {
				continue;
			}
			Object value = null;
			if (entry.getValue() instanceof PropertyDescriptor) {
				PropertyDescriptor property = (PropertyDescriptor) entry.getValue();
				value = property.getReadMethod().invoke(entity, null, null);

			} else if (entry.getValue() instanceof Field) {
				Field field = (Field) entry.getValue();
				field.setAccessible(true);
				value = field.get(entity);
			}
			if (null != value) {
				sqlEntry.append(" And " + entry.getKey()).append(" = :" + entry.getKey());
				sqlEntry.putParam(entry.getKey(), value);
			}
		}

		return sqlEntry;
	}

	@Override
	protected <T extends Identifiable<?>> List<SqlBuildEntry> buildManyToMany(Field field, T entity) throws Exception {
		return null;
	}

	@Override
	protected <T extends Identifiable<?>> List<SqlBuildEntry> buildManyToMany(PropertyDescriptor property, T entity)
			throws Exception {
		return null;
	}

}
